package psn.kiko.config.web;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import psn.kiko.config.properties.LoginInterceptProperties;
import psn.kiko.config.properties.ResourceHandlerProperties;
import psn.kiko.config.properties.SwaggerApiDocProperties;
import psn.kiko.interceptor.AdminLoginHandlerInterceptor;
import psn.kiko.interceptor.UserLoginHandlerInterceptor;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.List;

/**
 * 注册web层相关组件
 */
@Slf4j
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport{
	@Autowired
	SwaggerApiDocProperties swaggerApiDocProperties;
	@Autowired
	AdminLoginHandlerInterceptor adminLoginHandlerInterceptor;
	@Autowired
	UserLoginHandlerInterceptor userLoginHandlerInterceptor;
	@Autowired
	LoginInterceptProperties loginInterceptProperties;
	@Autowired
	ResourceHandlerProperties resourceHandlerProperties;
	
	//swagger接口文档生成
	@Bean
	public Docket docket(){
		log.debug("{}接口文档: http://{}:{}/{}",
				swaggerApiDocProperties.getTitle(),
				swaggerApiDocProperties.getHost(),
				swaggerApiDocProperties.getPort(),
				swaggerApiDocProperties.getPathPattern());
		
		return new Docket(DocumentationType.SWAGGER_2)
				.apiInfo(getApiInfo())
				.groupName("管理端接口")
				.select()
				// 指定生成接口需要扫描的包
				.apis(RequestHandlerSelectors.basePackage(swaggerApiDocProperties.getBasePackage()))
				.paths(PathSelectors.any())
				.build();
	}
	
	private ApiInfo getApiInfo(){
		ApiInfo apiInfo=new ApiInfoBuilder()
				.title(swaggerApiDocProperties.getTitle())
				.version(swaggerApiDocProperties.getVersion())
				.description(swaggerApiDocProperties.getDescription())
				.build();
		return apiInfo;
	}
	
	/**
	 * 设置静态资源映射：请求url模式和资源位置的映射关系
	 */
	@Override
	protected void addResourceHandlers(ResourceHandlerRegistry registry){
		log.debug("静态资源映射配置信息：");
		for(ResourceHandlerProperties.ResourceHandlerLocationMapping mapping: resourceHandlerProperties.getResourceHandlerLocationMappings()){
			log.debug("url模式：{}，资源位置：{}",mapping.getResourcePatterns(),mapping.getResourceLocations());
		}
		//已配置的静态资源：
		//1、swagger接口文档静态资源
		//2、上传文件静态资源
		for(ResourceHandlerProperties.ResourceHandlerLocationMapping mapping: resourceHandlerProperties.getResourceHandlerLocationMappings()){
			registry.addResourceHandler(mapping.getResourcePatterns())
					.addResourceLocations(mapping.getResourceLocations());
		}
	}
	
	//扩展消息转换器
	@Override
	protected void extendMessageConverters(List<HttpMessageConverter<?>> converters){
		log.debug("注册一个消息转换器...");
		//创建一个消息转换器
		MappingJackson2HttpMessageConverter converter=new MappingJackson2HttpMessageConverter();
		//为消息转换器设置对象转换器，对象转换器可以将对象序列化为JSON
		converter.setObjectMapper(new JacksonObjectMapper());
		//将自己的转换器加入容器
		converters.add(0,converter);
	}
	
	//注册处理器拦截器
	@Override
	protected void addInterceptors(InterceptorRegistry registry){
		log.debug("开始注册管理端处理器拦截器,放行路径:{},拦截路径:{}",loginInterceptProperties.getAdminExcludePaths(),
				loginInterceptProperties.getAdminIncludePaths());
		log.debug("开始注册管理端处理器拦截器,放行路径:{},拦截路径:{}",loginInterceptProperties.getUserExcludePaths(),
				loginInterceptProperties.getUserIncludePaths());
		
		//注册管理端处理器拦截器
		registry.addInterceptor(adminLoginHandlerInterceptor)
				.addPathPatterns(loginInterceptProperties.getAdminIncludePaths())
				.excludePathPatterns(loginInterceptProperties.getAdminExcludePaths());
		
		//注册用户端处理器拦截器
		registry.addInterceptor(userLoginHandlerInterceptor)
				.addPathPatterns(loginInterceptProperties.getUserIncludePaths())
				.excludePathPatterns(loginInterceptProperties.getUserExcludePaths());
	}
	
}
